<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Tasks;

use Srv\Apps\Proto\VO\Common\PushMsgVO;
use Srv\Conf\ConfModel\JPushConf;
use Srv\Libs\Frame\TaskAbstract;
use Srv\Libs\Plugins\JPush\JPushMsg;
use Swoole\Coroutine;
use Swoole\WebSocket\Server;

final class JPushSendTask extends TaskAbstract
{
    private int $delayTimeMill                      = 0;    // 发送延迟时长[毫秒]
    private ?JPushConf $JPushConf                   = null; // JPushConf
    private int $runType                            = 0;    // runType
    private const RUN_TYPE_DEL_ALIAS_TAG            = 1;
    private const RUN_TYPE_SET_ALIAS_TAG            = 2;
    private const RUN_TYPE_SEND_TO_REGID            = 3;
    private const RUN_TYPE_SEND_TO_USER             = 4;
    private const RUN_TYPE_PUSH_USER_ALL_DEVICE_MSG = 5;
    private const RUN_TYPE_PUSH_USER_MSG            = 6;
    private const RUN_TYPE_PUSH_GROUP_SUB_MSG       = 7;
    private const RUN_TYPE_PUSH_GROUP_MSG           = 8;
    private array $clearRegIdList                   = [];
    private string $setRegId                        = '';
    private string $setAliasName                    = '';
    private array $setTagNameList                   = [];
    private array $sendToRegIdData                  = [];
    private array $sendToUserData                   = [];
    private array $pushUserMsgAllDeviceData         = [];
    private array $pushUserMsgData                  = [];
    private array $pushGroupSubMsgData              = [];
    private array $pushGroupMsgData                 = [];

    /**
     * @param string $envStr
     * @param int $delayTimeMill
     * __construct
     */
    public function __construct(string $envStr, int $delayTimeMill)
    {
        $this->envStr           = $envStr;
        $this->delayTimeMill    = min(max($delayTimeMill, 0), 86400*1000);
    }

    /**
     * @param string $envStr
     * @param int $delayTimeMill
     * @return static
     * create
     */
    public static function create(string $envStr = '', int $delayTimeMill = 0):self
    {
        $__class__              = self::class;
        return new $__class__($envStr, $delayTimeMill);
    }

    /**
     * @param Server|null $WebSocketServer
     * @return void
     * runBefore
     */
    public function runBefore(?Server $WebSocketServer): void
    {
    }

    /**
     * @param Server|null $WebSocketServer
     * @return void
     * run
     */
    public function run(?Server $WebSocketServer): void
    {
        if($this->delayTimeMill > 0) Coroutine::sleep($this->delayTimeMill/1000);
        switch($this->runType){
            case self::RUN_TYPE_DEL_ALIAS_TAG:{
                (new JPushMsg($this->JPushConf))->clearAliasAndTagsBatch($this->clearRegIdList);
                break;
            }
            case self::RUN_TYPE_SET_ALIAS_TAG:{
                (new JPushMsg($this->JPushConf))->setTags($this->setRegId, $this->setAliasName, $this->setTagNameList, [], true);
                break;
            }
            case self::RUN_TYPE_SEND_TO_REGID:{
                (new JPushMsg($this->JPushConf))->sendToRegIdList(...$this->sendToRegIdData);
                break;
            }
            case self::RUN_TYPE_SEND_TO_USER:{
                (new JPushMsg($this->JPushConf))->sendToTagAliasList(...$this->sendToUserData);
                break;
            }
            case self::RUN_TYPE_PUSH_USER_ALL_DEVICE_MSG:{  // 发送用户所有设备推送消息
                (new JPushMsg($this->JPushConf))->sendPushUserAllDeviceMsg(...$this->pushUserMsgAllDeviceData);
                break;
            }
            case self::RUN_TYPE_PUSH_USER_MSG:{             // 发送用户当前或最后设备推送消息
                (new JPushMsg($this->JPushConf))->sendPushUserMsg(...$this->pushUserMsgData);
                break;
            }
            case self::RUN_TYPE_PUSH_GROUP_SUB_MSG:{        // 发送群组订阅推送消息
                (new JPushMsg($this->JPushConf))->sendPushGroupSubMsg(...$this->pushGroupSubMsgData);
                break;
            }
            case self::RUN_TYPE_PUSH_GROUP_MSG:{            // 发送群组推送消息
                (new JPushMsg($this->JPushConf))->sendPushGroupMsg(...$this->pushGroupMsgData);
                break;
            }
        }
    }

    /**
     * @param Server|null $WebSocketServer
     * @return void
     * runAfter
     */
    public function runAfter(?Server $WebSocketServer): void
    {
    }

    /**
     * @param JPushConf $JPushConf
     * @return $this
     * setJPushConf
     */
    public function setJPushConf(JPushConf $JPushConf):self
    {
        if($this->isTask()) return $this;
        $this->JPushConf    = $JPushConf;
        return $this;
    }

    /**
     * @param array $pushRegIdList
     * @return $this
     * clearAliasAndTags
     */
    public function clearAliasAndTags(array $pushRegIdList):self
    {
        if($this->isTask()) return $this;
        $this->runType          = self::RUN_TYPE_DEL_ALIAS_TAG;
        $this->clearRegIdList   = $pushRegIdList;
        return $this;
    }

    /**
     * @param string $pushRegId
     * @param string $aliasName
     * @param array $tagNameList
     * @return $this
     * setAliasAndTags
     */
    public function setAliasAndTags(string $pushRegId, string $aliasName, array $tagNameList):self
    {
        if($this->isTask()) return $this;
        $this->runType          = self::RUN_TYPE_SET_ALIAS_TAG;
        $this->setRegId         = $pushRegId;
        $this->setAliasName     = $aliasName;
        $this->setTagNameList   = $tagNameList;
        return $this;
    }

    /**
     * @param array $regIdList
     * @param string $msgText
     * @param string $title
     * @param array $extData
     * @param array $pushSet
     * @return $this
     * sendToRegId
     */
    public function sendToRegId(array $regIdList, string $msgText, string $title = '', array $extData = [], array $pushSet = []):self
    {
        if($this->isTask()) return $this;
        $this->runType          = self::RUN_TYPE_SEND_TO_REGID;
        $this->sendToRegIdData  = [$regIdList, $msgText, $title, $extData, $pushSet];
        return $this;
    }

    /**
     * @param array $aliasList
     * @param array $tagList
     * @param array $tagAndList
     * @param array $tagNotList
     * @param string $msgText
     * @param string $title
     * @param array $extData
     * @param array $pushSet
     * @return $this
     * sendToUser
     */
    public function sendToUser(array $aliasList, array $tagList, array $tagAndList, array $tagNotList, string $msgText, string $title = '', array $extData = [], array $pushSet = []):self
    {
        if($this->isTask()) return $this;
        $this->runType                  = self::RUN_TYPE_SEND_TO_USER;
        $this->sendToUserData           = [$aliasList, $tagList, $tagAndList, $tagNotList, $msgText, $title, $extData, $pushSet];
        return $this;
    }

    /**
     * @param PushMsgVO $PushMsgVO
     * @param array $userIdRecvList
     * @param array $pushSet
     * @return $this
     * sendPushUserAllDeviceMsg
     */
    public function sendPushUserAllDeviceMsg(PushMsgVO $PushMsgVO, array $userIdRecvList, array $pushSet = []):self
    {
        if($this->isTask()) return $this;
        $this->runType                  = self::RUN_TYPE_PUSH_USER_ALL_DEVICE_MSG;
        $this->pushUserMsgAllDeviceData = [$PushMsgVO, $userIdRecvList, $pushSet];
        return $this;
    }

    /**
     * @param PushMsgVO $PushMsgVO
     * @param array $userIdRecvList
     * @param array $pushSet
     * @return $this
     * sendPushUserMsg
     */
    public function sendPushUserMsg(PushMsgVO $PushMsgVO, array $userIdRecvList, array $pushSet = []):self
    {
        if($this->isTask()) return $this;
        $this->runType                  = self::RUN_TYPE_PUSH_USER_MSG;
        $this->pushUserMsgData          = [$PushMsgVO, $userIdRecvList, $pushSet];
        return $this;
    }

    /**
     * @param PushMsgVO $PushMsgVO
     * @param int $groupId
     * @param array $userIdRecvList
     * @param array $userIdNotList
     * @param array $pushSet
     * @return $this
     * sendPushGroupSubMsg
     */
    public function sendPushGroupSubMsg(PushMsgVO $PushMsgVO, int $groupId, array $userIdRecvList = [], array $userIdNotList = [], array $pushSet = []):self
    {
        if($this->isTask()) return $this;
        $this->runType                  = self::RUN_TYPE_PUSH_GROUP_SUB_MSG;
        $this->pushGroupSubMsgData      = [$PushMsgVO, $groupId, $userIdRecvList, $userIdNotList, $pushSet];
        return $this;
    }

    /**
     * @param PushMsgVO $PushMsgVO
     * @param int $groupId
     * @param array $userIdNotList
     * @param array $pushSet
     * @return $this
     * sendPushGroupMsg
     */
    public function sendPushGroupMsg(PushMsgVO $PushMsgVO, int $groupId, array $userIdNotList = [], array $pushSet = []):self
    {
        if($this->isTask()) return $this;
        $this->runType                  = self::RUN_TYPE_PUSH_GROUP_SUB_MSG;
        $this->pushGroupMsgData         = [$PushMsgVO, $groupId, $userIdNotList, $pushSet];
        return $this;
    }
}